package utils

import (
	"fmt"
	"net/url"
	"path/filepath"
	"sync"
	"sync/atomic"
	"time"
	"webpagedown3/pkg/task"
)

func DownloadWithRetry(downloadTask *task.DownloadTask, maxDepth int, downloadResources bool, taskCh chan<- *task.DownloadTask, activeCount *int32, mutex *sync.Mutex) error {
	defer func() {
		atomic.AddInt32(activeCount, -1)
		// 如果没有活跃任务且通道为空，关闭通道
		if atomic.LoadInt32(activeCount) == 0 {
			mutex.Lock()
			if atomic.LoadInt32(activeCount) == 0 && len(taskCh) == 0 {
				close(taskCh)
			}
			mutex.Unlock()
		}
	}()
	for downloadTask.Retries < downloadTask.MaxRetries {
		err := DownloadFile(downloadTask)
		if err == nil {
			// 下载成功
			fmt.Printf("成功下载: %s\n", downloadTask.URL)

			// 如果是HTML文件且需要递归下载
			if isHTMLFile(downloadTask.TargetPath) && maxDepth > 0 {
				// 提取链接和资源
				links, resources, err := extractLinksAndResources(downloadTask.TargetPath, downloadTask.URL)
				if err != nil {
					return fmt.Errorf("提取链接失败 %s: %v", downloadTask.URL, err)
				} else {
					// 递归下载链接
					for _, link := range links {
						// 检查是否已下载过该URL
						// fmt.Printf("DownloadWithRetry: downloadTask.DownloadedURL = %v\n", downloadTask.DownloadedURL)
						if _, loaded := downloadTask.DownloadedURL.LoadOrStore(link, true); loaded {
							continue
						}

						// 创建新的下载任务
						parsedURL, _ := url.Parse(link)
						urlDir := filepath.Join(filepath.Dir(downloadTask.TargetPath), getPathFromURL(parsedURL))
						fileName := filepath.Base(parsedURL.Path)
						if fileName == "" || fileName == "." || fileName == "/" || fileName == "//" || fileName == "\\" {
							fileName = "index.html"
						}

						newTask := &task.DownloadTask{
							URL:           link,
							TargetPath:    filepath.Join(urlDir, fileName),
							MaxRetries:    downloadTask.MaxRetries,
							DownloadedURL: downloadTask.DownloadedURL,
						}
						// fmt.Printf("DownloadWithRetry: newTask.DownloadedURL = %v\n", newTask.DownloadedURL)
						// 发送到任务通道
						//mutex.Lock() // 不需要加锁，因为activeCount是原子计数器
						atomic.AddInt32(activeCount, 1)
						//mutex.Unlock() // 不需要解锁，因为activeCount是原子计数器
						taskCh <- newTask
					}

					// 下载资源文件
					if downloadResources {
						for _, res := range resources {
							// 检查是否已下载过该资源
							// fmt.Printf("DownloadWithRetry: downloadTask.DownloadedURL = %v\n", downloadTask.DownloadedURL)
							if _, loaded := downloadTask.DownloadedURL.LoadOrStore(res, true); loaded {
								continue
							}
							// 创建资源下载任务
							parsedURL, _ := url.Parse(res)
							resDir := filepath.Join(filepath.Dir(downloadTask.TargetPath), getPathFromURL(parsedURL))
							fileName := filepath.Base(parsedURL.Path)
							if fileName == "" || fileName == "." {
								fileName = "resource"
							}

							resTask := &task.DownloadTask{
								URL:           res,
								TargetPath:    filepath.Join(resDir, fileName),
								MaxRetries:    downloadTask.MaxRetries,
								DownloadedURL: downloadTask.DownloadedURL,
							}
							// fmt.Printf("DownloadWithRetry: resTask.DownloadedURL = %v\n", resTask.DownloadedURL)
							// 发送到任务通道
							//mutex.Lock() // 不需要加锁，因为activeCount是原子计数器
							atomic.AddInt32(activeCount, 1)
							//mutex.Unlock() // 不需要解锁，因为activeCount是原子计数器
							taskCh <- resTask
						}
					}
				}
			}
			return nil
		}

		// 下载失败，重试
		downloadTask.Retries++
		fmt.Printf("下载失败 %s: %v (重试 %d/%d)\n", downloadTask.URL, err, downloadTask.Retries, downloadTask.MaxRetries)
		time.Sleep(time.Second * 1) // 重试前等待
	}
	return fmt.Errorf("下载失败，已达到最大重试次数: %s", downloadTask.URL)
}
